package com.demo.interceptor;

import com.demo.filter.CustomRequestWrapper;
import com.demo.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
 * @author wangfengchen
 */
@Slf4j
public class LogInterceptor implements HandlerInterceptor {

  private long startTime;


  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 如果不是映射到方法直接通过，跨域请求会先发送OPTIONS预检请求
    if (!(handler instanceof HandlerMethod)) {
      return true;
    }
    // OPTIONS请求用来刺探网络，所以直接放行
    if (HttpMethod.OPTIONS.toString().equalsIgnoreCase(request.getMethod())) {
      response.setStatus(HttpStatus.NO_CONTENT.value());
      return true;
    }
    log.info("开始处理请求......");
    startTime = System.currentTimeMillis();
    return true;
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    long endTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    sb.append("请求IP = ").append(IpUtil.getIpAddr(request)).append("，");
    sb.append("请求方式 = ").append(request.getMethod()).append("，");
    sb.append("请求地址 = ").append(request.getRequestURI()).append("，");
    String queryString = request.getQueryString();
    if (StringUtils.isNotBlank(queryString)) {
      String decodedQuery = URLDecoder.decode(queryString, StandardCharsets.UTF_8.toString());
      sb.append("请求路径参数 = ").append(decodedQuery).append("，");
    }
    if (HttpMethod.POST.toString().equals(request.getMethod())) {
      String body = new String(new CustomRequestWrapper(request).getBody());
      if (StringUtils.isNotBlank(body)) {
        sb.append("请求体参数 = ").append(body).append("，");
      }
    }
    sb.append("请求耗时 = ").append(endTime - startTime).append("ms").append("，");
    sb.append("响应码 = ").append(response.getStatus());
    log.info("处理请求结束，请求信息为：{}", sb);
  }

}
